/*
 *  Copyright 2019, dqsjqian(Mr.Zhang).  All right reserved.
 *
 *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF dqsjqian(Mr.Zhang).
 *  LTD.  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED TO THIRD
 *  PARTIES, COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 *  WITHOUT THE PRIOR WRITTEN PERMISSION OF dqsjqian(Mr.Zhang).
 *
 *
 *  Edit History:
 *
 *    2019-08-28 - Created by dqsjqian(Mr.Zhang) dqsjqian@163.com
 *
 */

/* 
CQHash is an extremely fast Hash algorithm, running at RAM speed limits.
It also successfully passes all tests from the SMHasher suite.

Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)

Name            Speed       Q.Score
CQHash          5.4 GB/s     10
CrapWow         3.2 GB/s      2
MumurHash 3a    2.7 GB/s     10
SpookyHash      2.0 GB/s     10
SBox            1.4 GB/s      9
Lookup3         1.2 GB/s      9
SuperFastHash   1.2 GB/s      1
CityHash64      1.05 GB/s    10
FNV             0.55 GB/s     5
CRC32           0.43 GB/s     9
MD5-32          0.33 GB/s    10
SHA1-32         0.28 GB/s    10

Q.Score is a measure of quality of the hash function.
It depends on successfully passing SMHasher test set.
10 is a perfect score.

A 64-bit version, named CQH64, is available since r35.
It offers much better speed, but for 64-bit applications only.
Name     Speed on 64 bits    Speed on 32 bits
CQH64       13.8 GB/s            1.9 GB/s
CQH32        6.8 GB/s            6.0 GB/s
*/

#ifndef CQHASH_H_5627135585666179
#define CQHASH_H_5627135585666179 1

#if defined (__cplusplus)
extern "C" {
#endif


/* ****************************
*  Definitions
******************************/
#include <stddef.h>   /* size_t */

typedef enum { CQH_OK=0, CQH_ERROR } CQH_errorcode;


/* ****************************
 *  API modifier
 ******************************/
/** CQH_INLINE_ALL (and CQH_PRIVATE_API)
 *  This is useful to include cqhash functions in `static` mode
 *  in order to inline them, and remove their symbol from the public list.
 *  Inlining can offer dramatic performance improvement on small keys.
 *  Methodology :
 *     #define CQH_INLINE_ALL
 *     #include "cqhash.h"
 * `cqhash.c` is automatically included.
 *  It's not useful to compile and link it as a separate module.
 */
#if defined(CQH_INLINE_ALL) || defined(CQH_PRIVATE_API)
#  ifndef CQH_STATIC_LINKING_ONLY
#    define CQH_STATIC_LINKING_ONLY
#  endif
#  if defined(__GNUC__)
#    define CQH_PUBLIC_API static __inline __attribute__((unused))
#  elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
#    define CQH_PUBLIC_API static inline
#  elif defined(_MSC_VER)
#    define CQH_PUBLIC_API static __inline
#  else
     /* this version may generate warnings for unused static functions */
#    define CQH_PUBLIC_API static
#  endif
#else
#  if defined(WIN32) && defined(_MSC_VER) && (defined(CQH_IMPORT) || defined(CQH_EXPORT))
#    ifdef CQH_EXPORT
#      define CQH_PUBLIC_API __declspec(dllexport)
#    elif CQH_IMPORT
#      define CQH_PUBLIC_API __declspec(dllimport)
#    endif
#  else
#    define CQH_PUBLIC_API   /* do nothing */
#  endif
#endif /* CQH_INLINE_ALL || CQH_PRIVATE_API */

/*! CQH_NAMESPACE, aka Namespace Emulation :
 *
 * If you want to include _and expose_ CQHash functions from within your own library,
 * but also want to avoid symbol collisions with other libraries which may also include CQHash,
 *
 * you can use CQH_NAMESPACE, to automatically prefix any public symbol from cqhash library
 * with the value of CQH_NAMESPACE (therefore, avoid NULL and numeric values).
 *
 * Note that no change is required within the calling program as long as it includes `cqhash.h` :
 * regular symbol name will be automatically translated by this header.
 */
#ifdef CQH_NAMESPACE
#  define CQH_CAT(A,B) A##B
#  define CQH_NAME2(A,B) CQH_CAT(A,B)
#  define CQH_versionNumber CQH_NAME2(CQH_NAMESPACE, CQH_versionNumber)
#  define CQH32 CQH_NAME2(CQH_NAMESPACE, CQH32)
#  define CQH32_createState CQH_NAME2(CQH_NAMESPACE, CQH32_createState)
#  define CQH32_freeState CQH_NAME2(CQH_NAMESPACE, CQH32_freeState)
#  define CQH32_reset CQH_NAME2(CQH_NAMESPACE, CQH32_reset)
#  define CQH32_update CQH_NAME2(CQH_NAMESPACE, CQH32_update)
#  define CQH32_digest CQH_NAME2(CQH_NAMESPACE, CQH32_digest)
#  define CQH32_copyState CQH_NAME2(CQH_NAMESPACE, CQH32_copyState)
#  define CQH32_canonicalFromHash CQH_NAME2(CQH_NAMESPACE, CQH32_canonicalFromHash)
#  define CQH32_hashFromCanonical CQH_NAME2(CQH_NAMESPACE, CQH32_hashFromCanonical)
#  define CQH64 CQH_NAME2(CQH_NAMESPACE, CQH64)
#  define CQH64_createState CQH_NAME2(CQH_NAMESPACE, CQH64_createState)
#  define CQH64_freeState CQH_NAME2(CQH_NAMESPACE, CQH64_freeState)
#  define CQH64_reset CQH_NAME2(CQH_NAMESPACE, CQH64_reset)
#  define CQH64_update CQH_NAME2(CQH_NAMESPACE, CQH64_update)
#  define CQH64_digest CQH_NAME2(CQH_NAMESPACE, CQH64_digest)
#  define CQH64_copyState CQH_NAME2(CQH_NAMESPACE, CQH64_copyState)
#  define CQH64_canonicalFromHash CQH_NAME2(CQH_NAMESPACE, CQH64_canonicalFromHash)
#  define CQH64_hashFromCanonical CQH_NAME2(CQH_NAMESPACE, CQH64_hashFromCanonical)
#endif


/* *************************************
*  Version
***************************************/
#define CQH_VERSION_MAJOR    0
#define CQH_VERSION_MINOR    7
#define CQH_VERSION_RELEASE  0
#define CQH_VERSION_NUMBER  (CQH_VERSION_MAJOR *100*100 + CQH_VERSION_MINOR *100 + CQH_VERSION_RELEASE)
CQH_PUBLIC_API unsigned CQH_versionNumber (void);


/*-**********************************************************************
*  32-bit hash
************************************************************************/
#if !defined (__VMS) \
  && (defined (__cplusplus) \
  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
#   include <stdint.h>
    typedef uint32_t CQH32_hash_t;
#else
    typedef unsigned int CQH32_hash_t;
#endif

/*! CQH32() :
    Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input".
    The memory between input & input+length must be valid (allocated and read-accessible).
    "seed" can be used to alter the result predictably.
    Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */
CQH_PUBLIC_API CQH32_hash_t CQH32 (const void* input, size_t length, unsigned int seed);

/*======   Streaming   ======*/
typedef struct CQH32_state_s CQH32_state_t;   /* incomplete type */
CQH_PUBLIC_API CQH32_state_t* CQH32_createState(void);
CQH_PUBLIC_API CQH_errorcode  CQH32_freeState(CQH32_state_t* statePtr);
CQH_PUBLIC_API void CQH32_copyState(CQH32_state_t* dst_state, const CQH32_state_t* src_state);

CQH_PUBLIC_API CQH_errorcode CQH32_reset  (CQH32_state_t* statePtr, unsigned int seed);
CQH_PUBLIC_API CQH_errorcode CQH32_update (CQH32_state_t* statePtr, const void* input, size_t length);
CQH_PUBLIC_API CQH32_hash_t  CQH32_digest (const CQH32_state_t* statePtr);

/*
 * Streaming functions generate the CQHash of an input provided in multiple segments.
 * Note that, for small input, they are slower than single-call functions, due to state management.
 * For small inputs, prefer `CQH32()` and `CQH64()`, which are better optimized.
 *
 * CQH state must first be allocated, using CQH*_createState() .
 *
 * Start a new hash by initializing state with a seed, using CQH*_reset().
 *
 * Then, feed the hash state by calling CQH*_update() as many times as necessary.
 * The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
 *
 * Finally, a hash value can be produced anytime, by using CQH*_digest().
 * This function returns the nn-bits hash as an int or long long.
 *
 * It's still possible to continue inserting input into the hash state after a digest,
 * and generate some new hashes later on, by calling again CQH*_digest().
 *
 * When done, free CQH state space if it was allocated dynamically.
 */

/*======   Canonical representation   ======*/

typedef struct { unsigned char digest[4]; } CQH32_canonical_t;
CQH_PUBLIC_API void CQH32_canonicalFromHash(CQH32_canonical_t* dst, CQH32_hash_t hash);
CQH_PUBLIC_API CQH32_hash_t CQH32_hashFromCanonical(const CQH32_canonical_t* src);

/* Default result type for CQH functions are primitive unsigned 32 and 64 bits.
 * The canonical representation uses human-readable write convention, aka big-endian (large digits first).
 * These functions allow transformation of hash result into and from its canonical format.
 * This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
 */


#ifndef CQH_NO_LONG_LONG
/*-**********************************************************************
*  64-bit hash
************************************************************************/
#if !defined (__VMS) \
  && (defined (__cplusplus) \
  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
#   include <stdint.h>
    typedef uint64_t CQH64_hash_t;
#else
    typedef unsigned long long CQH64_hash_t;
#endif

/*! CQH64() :
    Calculate the 64-bit hash of sequence of length "len" stored at memory address "input".
    "seed" can be used to alter the result predictably.
    This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark).
*/
CQH_PUBLIC_API CQH64_hash_t CQH64 (const void* input, size_t length, unsigned long long seed);

/*======   Streaming   ======*/
typedef struct CQH64_state_s CQH64_state_t;   /* incomplete type */
CQH_PUBLIC_API CQH64_state_t* CQH64_createState(void);
CQH_PUBLIC_API CQH_errorcode  CQH64_freeState(CQH64_state_t* statePtr);
CQH_PUBLIC_API void CQH64_copyState(CQH64_state_t* dst_state, const CQH64_state_t* src_state);

CQH_PUBLIC_API CQH_errorcode CQH64_reset  (CQH64_state_t* statePtr, unsigned long long seed);
CQH_PUBLIC_API CQH_errorcode CQH64_update (CQH64_state_t* statePtr, const void* input, size_t length);
CQH_PUBLIC_API CQH64_hash_t  CQH64_digest (const CQH64_state_t* statePtr);

/*======   Canonical representation   ======*/
typedef struct { unsigned char digest[8]; } CQH64_canonical_t;
CQH_PUBLIC_API void CQH64_canonicalFromHash(CQH64_canonical_t* dst, CQH64_hash_t hash);
CQH_PUBLIC_API CQH64_hash_t CQH64_hashFromCanonical(const CQH64_canonical_t* src);


#endif  /* CQH_NO_LONG_LONG */



#ifdef CQH_STATIC_LINKING_ONLY

/* ================================================================================================
   This section contains declarations which are not guaranteed to remain stable.
   They may change in future versions, becoming incompatible with a different version of the library.
   These declarations should only be used with static linking.
   Never use them in association with dynamic linking !
=================================================================================================== */

/* These definitions are only present to allow
 * static allocation of CQH state, on stack or in a struct for example.
 * Never **ever** use members directly. */

struct CQH32_state_s {
   CQH32_hash_t total_len_32;
   CQH32_hash_t large_len;
   CQH32_hash_t v1;
   CQH32_hash_t v2;
   CQH32_hash_t v3;
   CQH32_hash_t v4;
   CQH32_hash_t mem32[4];
   CQH32_hash_t memsize;
   CQH32_hash_t reserved;   /* never read nor write, might be removed in a future version */
};   /* typedef'd to CQH32_state_t */

#ifndef CQH_NO_LONG_LONG  /* remove 64-bit support */
struct CQH64_state_s {
   CQH64_hash_t total_len;
   CQH64_hash_t v1;
   CQH64_hash_t v2;
   CQH64_hash_t v3;
   CQH64_hash_t v4;
   CQH64_hash_t mem64[4];
   CQH32_hash_t memsize;
   CQH32_hash_t reserved[2];     /* never read nor write, might be removed in a future version */
};   /* typedef'd to CQH64_state_t */
#endif   /* CQH_NO_LONG_LONG */


/*-**********************************************************************
*  CQH3
*  New experimental hash
************************************************************************/
#ifndef CQH_NO_LONG_LONG


/* ============================================
 * CQH3 is a new hash algorithm,
 * featuring vastly improved speed performance
 * for both small and large inputs.
 * See full speed analysis at : http://fastcompression.blogspot.com/2019/03/presenting-cqh3.html
 * In general, expect CQH3 to run about ~2x faster on large inputs,
 * and >3x faster on small ones, though exact difference depend on platform.
 *
 * The algorithm is portable, will generate the same hash on all platforms.
 * It benefits greatly from vectorization units, but does not require it.
 *
 * CQH3 offers 2 variants, _64bits and _128bits.
 * When only 64 bits are needed, prefer calling the _64bits variant :
 * it reduces the amount of mixing, resulting in faster speed on small inputs.
 * It's also generally simpler to manipulate a scalar return type than a struct.
 *
 * The CQH3 algorithm is still considered experimental.
 * Produced results can still change between versions.
 * It's possible to use it for ephemeral data, but avoid storing long-term values for later re-use.
 *
 * The API currently supports one-shot hashing only.
 * The full version will include streaming capability, and canonical representation.
 *
 * There are still a number of opened questions that community can influence during the experimental period.
 * I'm trying to list a few of them below, though don't consider this list as complete.
 *
 * - 128-bits output type : currently defined as a structure of 2 64-bits fields.
 *                          That's because 128-bit values do not exist in C standard.
 *                          Note that it means that, at byte level, result is not identical depending on endianess.
 *                          However, at field level, they are identical on all platforms.
 *                          The canonical representation will solve the issue of identical byte-level representation across platforms,
 *                          which is necessary for serialization.
 *                          Would there be a better representation for a 128-bit hash result ?
 *                          Are the names of the inner 64-bit fields important ? Should they be changed ?
 *
 * - Canonical representation : for the 64-bit variant, canonical representation is the same as CQH64() (aka big-endian).
 *                          What should it be for the 128-bit variant ?
 *                          Since it's no longer a scalar value, big-endian representation is no longer an obvious choice.
 *                          One possibility : represent it as the concatenation of two 64-bits canonical representation (aka 2x big-endian)
 *                          Another one : represent it in the same order as natural order in the struct for little-endian platforms.
 *                                        Less consistent with existing convention for CQH32/CQH64, but may be more natural for little-endian platforms.
 *
 * - Associated functions for 128-bit hash : simple things, such as checking if 2 hashes are equal, become more difficult with struct.
 *                          Granted, it's not terribly difficult to create a comparator, but it's still a workload.
 *                          Would it be beneficial to declare and define a comparator function for CQH128_hash_t ?
 *                          Are there other operations on CQH128_hash_t which would be desirable ?
 *
 * - Seed type for 128-bits variant : currently, it's a single 64-bit value, like the 64-bit variant.
 *                          It could be argued that it's more logical to offer a 128-bit seed input parameter for a 128-bit hash.
 *                          Although it's also more difficult to use, since it requires to declare and pass a structure instead of a value.
 *                          It would either replace current choice, or add a new one.
 *                          Farmhash, for example, offers both variants (the 128-bits seed variant is called `doubleSeed`).
 *                          If both 64-bit and 128-bit seeds are possible, which variant should be called CQH128 ?
 *
 * - Result for len==0 : Currently, the result of hashing a zero-length input is `0`.
 *                          It seems okay as a return value when using all "default" secret and seed (it used to be a request for CQH32/CQH64).
 *                          But is it still fine to return `0` when secret or seed are non-default ?
 *                          Are there use case which would depend on a different hash result when the secret is different ?
 */

#ifdef CQH_NAMESPACE
#  define CQH3_64bits CQH_NAME2(CQH_NAMESPACE, CQH3_64bits)
#  define CQH3_64bits_withSecret CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_withSecret)
#  define CQH3_64bits_withSeed CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_withSeed)

#  define CQH3_64bits_createState CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_createState)
#  define CQH3_64bits_freeState CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_freeState)
#  define CQH3_64bits_copyState CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_copyState)
#  define CQH3_64bits_reset CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_reset)
#  define CQH3_64bits_reset_withSeed CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_reset_withSeed)
#  define CQH3_64bits_reset_withSecret CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_reset_withSecret)
#  define CQH3_64bits_update CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_update)
#  define CQH3_64bits_digest CQH_NAME2(CQH_NAMESPACE, CQH3_64bits_digest)

#  define CQH3_128bits CQH_NAME2(CQH_NAMESPACE, CQH3_128bits)
#  define CQH3_128bits_withSeed CQH_NAME2(CQH_NAMESPACE, CQH3_128bits_withSeed)
#  define CQH128 CQH_NAME2(CQH_NAMESPACE, CQH128)
#endif

/* CQH3_64bits() :
 * default 64-bit variant, using default secret and default seed of 0.
 * it's also the fastest one. */
CQH_PUBLIC_API CQH64_hash_t CQH3_64bits(const void* data, size_t len);

/* CQH3_64bits_withSecret() :
 * It's possible to provide any blob of bytes as a "secret" to generate the hash.
 * This makes it more difficult for an external actor to prepare an intentional collision.
 * The secret *must* be large enough (>= CQH3_SECRET_SIZE_MIN).
 * It should consist of random bytes.
 * Avoid repeating same character, and especially avoid swathes of \0.
 * Avoid repeating sequences of bytes within the secret.
 * Failure to respect these conditions will result in a bad quality hash.
 */
#define CQH3_SECRET_SIZE_MIN 136
CQH_PUBLIC_API CQH64_hash_t CQH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);

/* CQH3_64bits_withSeed() :
 * This variant generates on the fly a custom secret,
 * based on the default secret, altered using the `seed` value.
 * While this operation is decently fast, note that it's not completely free.
 * note : seed==0 produces same results as CQH3_64bits() */
CQH_PUBLIC_API CQH64_hash_t CQH3_64bits_withSeed(const void* data, size_t len, CQH64_hash_t seed);


/* streaming 64-bit */

#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)   /* C11+ */
#  include <stdalign.h>
#  define CQH_ALIGN(n)      alignas(n)
#elif defined(__GNUC__)
#  define CQH_ALIGN(n)      __attribute__ ((aligned(n)))
#elif defined(_MSC_VER)
#  define CQH_ALIGN(n)      __declspec(align(n))
#else
#  define CQH_ALIGN(n)   /* disabled */
#endif

typedef struct CQH3_state_s CQH3_state_t;

#define CQH3_SECRET_DEFAULT_SIZE 192   /* minimum CQH3_SECRET_SIZE_MIN */
#define CQH3_INTERNALBUFFER_SIZE 256
struct CQH3_state_s {
   CQH_ALIGN(64) CQH64_hash_t acc[8];
   CQH_ALIGN(64) char customSecret[CQH3_SECRET_DEFAULT_SIZE];  /* used to store a custom secret generated from the seed. Makes state larger. Design might change */
   CQH_ALIGN(64) char buffer[CQH3_INTERNALBUFFER_SIZE];
   const void* secret;
   CQH32_hash_t bufferedSize;
   CQH32_hash_t nbStripesPerBlock;
   CQH32_hash_t nbStripesSoFar;
   CQH32_hash_t reserved32;
   CQH32_hash_t reserved32_2;
   CQH32_hash_t secretLimit;
   CQH64_hash_t totalLen;
   CQH64_hash_t seed;
   CQH64_hash_t reserved64;
};   /* typedef'd to CQH3_state_t */

/* Streaming requires state maintenance.
 * This operation costs memory and cpu.
 * As a consequence, streaming is slower than one-shot hashing.
 * For better performance, prefer using one-short functions anytime possible. */

CQH_PUBLIC_API CQH3_state_t* CQH3_64bits_createState(void);
CQH_PUBLIC_API CQH_errorcode CQH3_64bits_freeState(CQH3_state_t* statePtr);
CQH_PUBLIC_API void CQH3_64bits_copyState(CQH3_state_t* dst_state, const CQH3_state_t* src_state);

/* CQH3_64bits_reset() :
 * initialize with default parameters.
 * result will be equivalent to `CQH3_64bits()` */
CQH_PUBLIC_API CQH_errorcode CQH3_64bits_reset(CQH3_state_t* statePtr);
/* CQH3_64bits_reset_withSeed() :
 * generate a custom secret from `seed`, and store it into state.
 * digest will be equivalent to `CQH3_64bits_withSeed()` */
CQH_PUBLIC_API CQH_errorcode CQH3_64bits_reset_withSeed(CQH3_state_t* statePtr, CQH64_hash_t seed);
/* CQH3_64bits_reset_withSecret() :
 * `secret` is referenced, and must outlive the hash streaming session.
 * secretSize must be >= CQH3_SECRET_SIZE_MIN.
 */
CQH_PUBLIC_API CQH_errorcode CQH3_64bits_reset_withSecret(CQH3_state_t* statePtr, const void* secret, size_t secretSize);

CQH_PUBLIC_API CQH_errorcode CQH3_64bits_update (CQH3_state_t* statePtr, const void* input, size_t length);
CQH_PUBLIC_API CQH64_hash_t  CQH3_64bits_digest (const CQH3_state_t* statePtr);


/* 128-bit */

typedef struct {
    CQH64_hash_t low64;
    CQH64_hash_t high64;
} CQH128_hash_t;

CQH_PUBLIC_API CQH128_hash_t CQH3_128bits(const void* data, size_t len);
CQH_PUBLIC_API CQH128_hash_t CQH3_128bits_withSeed(const void* data, size_t len, CQH64_hash_t seed);  /* == CQH128() */
CQH_PUBLIC_API CQH128_hash_t CQH128(const void* data, size_t len, CQH64_hash_t seed);



#endif  /* CQH_NO_LONG_LONG */


/*-**********************************************************************
*  CQH_INLINE_ALL
************************************************************************/
#if defined(CQH_INLINE_ALL) || defined(CQH_PRIVATE_API)
#  include "cqhash.cpp"   /* include cqhash function bodies as `static`, for inlining */
#endif


#endif /* CQH_STATIC_LINKING_ONLY */


#if defined (__cplusplus)
}
#endif

#endif /* CQHASH_H_5627135585666179 */
